package tech.waterism.topo.preprocessor;

import lombok.extern.slf4j.Slf4j;
import tech.waterism.topo.context.CalculationContext;
import tech.waterism.topo.model.*;

import java.util.List;

/**
 * 数据预处理器
 * 
 * <p>负责在计算开始前的数据准备工作
 * 
 * <h3>核心职责：</h3>
 * <ul>
 *   <li>校验数据完整性</li>
 *   <li>初始化分洪排洪数据（清零）</li>
 *   <li>构建索引映射</li>
 *   <li>补充缺失的水位库容曲线</li>
 * </ul>
 * 
 * @author waterism
 * @since 1.0.0
 */
@Slf4j
public class DataPreprocessor {
    
    /**
     * 校验节点数据完整性
     * 
     * @param nodes 拓扑节点列表
     * @throws IllegalArgumentException 如果数据不完整
     */
    public void validateNodes(List<TopoNode> nodes) {
        if (nodes == null || nodes.isEmpty()) {
            throw new IllegalArgumentException("拓扑节点列表不能为空");
        }
        
        for (TopoNode node : nodes) {
            if (node.getStcd() == null || node.getStcd().isEmpty()) {
                throw new IllegalArgumentException("节点站码不能为空");
            }
            
            if (node.getData() == null || node.getData().isEmpty()) {
                throw new IllegalArgumentException(
                        String.format("节点 %s (%s) 缺少时序数据", node.getStcd(), node.getStnm()));
            }
        }
        
        log.info("数据校验通过，共 {} 个节点", nodes.size());
    }
    
    /**
     * 初始化分洪排洪数据
     * <p>将所有节点的 QDvr 和 QDsc 清零
     * 
     * @param nodes 拓扑节点列表
     */
    public void initializeDiversionAndDischarge(List<TopoNode> nodes) {
        if (nodes == null) {
            return;
        }
        
        for (TopoNode node : nodes) {
            if (node.getData() == null) {
                continue;
            }
            
            for (TimeSeriesData data : node.getData()) {
                data.setQDvr(0.0);
                data.setQDsc(0.0);
            }
        }
        
        log.debug("分洪排洪数据初始化完成");
    }
    
    /**
     * 构建节点索引映射
     * <p>建立站码到索引位置的映射，用于快速查找和联调回溯
     * 
     * @param nodes 拓扑节点列表
     * @param context 计算上下文
     */
    public void buildNodeIndexMap(List<TopoNode> nodes, CalculationContext context) {
        if (nodes == null) {
            return;
        }
        
        for (int i = 0; i < nodes.size(); i++) {
            TopoNode node = nodes.get(i);
            context.getNodeIndexMap().put(node.getStcd(), i);
        }
        
        log.debug("节点索引映射构建完成，共 {} 个节点", nodes.size());
    }
    
    /**
     * 构建联调映射
     * <p>建立联调组的触发条件映射
     * 
     * @param groups 联调组列表
     * @param context 计算上下文
     */
    public void buildJointDispatchMaps(List<JointDispatchGroup> groups, CalculationContext context) {
        if (groups == null || groups.isEmpty()) {
            return;
        }
        
        for (JointDispatchGroup group : groups) {
            // 触发条件映射：联调组ID -> 上游起点站码列表
            context.getJointTriggerMap().put(group.getJmsid(), group.getUpstreamNodes());
            
            // 联调组详情映射
            context.getJointGroupMap().put(group.getJmsid(), group);
        }
        
        log.info("联调映射构建完成，共 {} 个联调组", groups.size());
    }
}

